namespace EFS.EventLog.Writers
{
	internal class File
	{
		// synk access
		private static object syncAccess = new object();

		/// Property Instance (singleton): Get
		public static File Instance { get; private set; }

		/// SW
		private static System.IO.StreamWriter sw = null;

		/// <summary>
		/// Static constructor to init local instance
		/// </summary>
		static File()
		{
			Instance = new File();
		}

		/// <summary>
		/// Contructor
		/// </summary>
		private File()
		{
		}

		/// <summary>
		/// Keep log file open
		/// </summary>
		public static void Open()
		{
			lock (syncAccess)
			{
				if (null == sw)
				{
					// app log
					sw = new System.IO.StreamWriter(ApplicationLogFilePath, true);
				}
			}
		}

		/// Close open stream
		public static System.Boolean IsOpen
		{
			get
			{
				// app log
				return (null != sw);
			}
		}

		/// Close open stream
		public static void Close()
		{
			lock (syncAccess)
			{
				// app log
				if (null != sw)
				{
					// close
					sw.Close();
					sw = null;
				}
			}
		}

   		// Log entry
		public void Write(System.String message)
		{
			lock (syncAccess)
			{
				try
				{
					// sw
					System.IO.StreamWriter sw = GetOpenStreamWriter();
					
					// check already open one
					if (null == sw)
					{
						sw = new System.IO.StreamWriter(ApplicationLogFilePath, true);
					}

					// write
					sw.WriteLine(message);

					// check if must close or flush
					if (null == File.sw)
					{
						sw.Close();
					}
					else
					{
						sw.Flush();
					}
				}
				catch (System.Exception e)
				{
					System.Diagnostics.Debug.WriteLine(e);
				}
			}
		}

		/// <summary>
		/// get open 
		/// </summary>
		/// <returns></returns>
		private System.IO.StreamWriter GetOpenStreamWriter()
		{
 			// lock
			lock(syncAccess)
			{
				// check
				if (null == File.sw)
				{
					return null;
				}

				// get fs
				System.IO.FileStream fs = sw.BaseStream as System.IO.FileStream;

				// check correct file
				if (ApplicationLogFilePath == fs.Name)
				{
					return sw;
				}

				// re-open
				Close();

				// open
				Open();

				// done
				return File.sw;
			}
		}

		/// <summary>
		/// add date to filename
		/// </summary>
		public static System.String ApplicationLogFilePath
		{
			get
			{
				// add filename "yyy-mm-dd.txt" to filepath from logconfig.xml file
				return System.String.Format("{0}{1}.txt", ApplicationLogPath, System.DateTime.Now.ToString("yyyy-MM-dd"));
			}
		}

		public static System.String ApplicationLogPath
		{
			get
			{
				// filepath from logconfig.xml file
				return System.String.Format("{0}", EFS.EventLog.Config.Log.FileLog.FilePath.Replace("%TEMP%\\", System.IO.Path.GetTempPath()));
			}
		}
	}
}